generatorを返す多重forループがあるとき、ループの深さを減らしたい (Python)
Pythonで、generatorを返す多重forループがあるとき、ループの深さを減らしたいが方法がわからないyosider.icon
code:original.py
def f():
for i in I:
for j in J:
yield h(i, j)
例えば複数の関数に分割したい
こんな感じに分割できるが、Iが大きい時にf()が遅い
code:py
from itertools import chain
def f():
generators = []
for i in I:
generators.append(g(i))
return chain(*generators)
def g(i):
for j in J:
yield h(i, j)
実際は5重ループで、flake8というやつにtoo complexと言われてcommitできずに困っている flake8を無効にすればいいのかもしれない
nishio.icon
code:python
def f():
generators = []
for i in I:
generators.append(g(i))
return chain(*generators)
ここでeagerなリストを作る必要はないのでは
code:python
def g(i):
for j in range(3):
yield f"{i}{j}"
def f():
return chain(*(g(i) for i in "ABC"))
print(list(f()))
やりたいことはこういうこと?
ありがとうございますyosider.icon
内包表記にしたぶん速くなったぽいですが、外側のループが大きい時に遅い問題がやはりあります。。yosider.icon
https://gyazo.com/73f9c80321f7b786b1eccdcb4e6a2cb7
chain(*iterables)は引数をunpackして渡すので、iterablesが展開されてしまう
あー、そうか、確かにnishio.icon
chain.from_iterable()というのを使うといけた!yosider.icon
https://gyazo.com/7f265c0f74269d2660ce1e2ef5ba6ec6
chain.from_iterable(iterables)はiterablesを展開せずに渡せる
listのほうではダメ
https://gyazo.com/a0624ead1f0be93c4e7efad585b1e1cb
🎉nishio.icon